package cn.tedu.csmall.stock.webapi.controller;

import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall.commons.restful.JsonResult;
import cn.tedu.csmall.commons.restful.ResponseCode;
import cn.tedu.csmall.stock.service.IStockService;
import cn.tedu.csmall.stock.webapi.error.StockBlockError;
import cn.tedu.csmall.stock.webapi.error.StockFallbackError;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.sun.deploy.security.BlockedException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/base/stock")
@Api(tags = "库存管理")
public class StockController {
    @Autowired
    private IStockService stockService;

    @PostMapping("/reduce/count")
    @ApiOperation("减少商品库存数")
    //@SentinelResource注解标记的控制层方法，会被Sentinel进行管理
    //在这个方法第一次运行，可以在Sentinel仪表盘界面中设置限流规则
    //"减少库存的方法"设置当前方法在仪表盘中显示的名称
    //blockHandler指定请求被限流使运行的方法的名称(blockError)
    //fallback指定降级方法名
//    @SentinelResource(value = "减少库存的方法",
//    blockHandler = "blockError",
//    fallback = "fallbackError")
    @SentinelResource(value = "减少库存的方法",
    blockHandlerClass = StockBlockError.class,blockHandler = "blockError",
    fallbackClass = StockFallbackError.class,fallback = "fallbackError")
    public JsonResult reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO){
        //60%的概率,抛出异常
        if(Math.random()<0.6)
            System.out.println(5/0);
        stockService.reduceCommodityCount(stockReduceCountDTO);
        return JsonResult.ok("商品库存减少完成！");
    }
    //Sentinel自定义限流方法的定义的规则
    //1.访问修饰符是public
    //2.返回值类型必须和被限流的方法的返回值类型一致
    //3.方法名称必须是被限流方法上限流注解中blockHandler指定的方法名称
    //4.方法参数列表必须和被限流的方法一致，而且还要添加一个BlockException类型的参数
//    public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO,
//                                 BlockException e){
//        //限流方法一般直接返回限流信息即可
//        return JsonResult.failed(ResponseCode.BAD_REQUEST,"服务器繁忙，请稍后重试!");
//    }
//    //Sentinel自定义降级方法
//    //降级方法的返回值要和被降级的方法的返回值类型一致
//    //降级方法的参数列表要和被降级的方法的参数列表类型一致，还可以添加一个异常的参数类型
//    public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO){
//        return JsonResult.failed(ResponseCode.BAD_REQUEST,"运行方法失败，服务降级");
//    }
}
